
<script src="http://protozoa.googlecode.com/svn/trunk/js/functions.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/dom.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/dom.event.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/utils.js"></script>

<!--
<script src="/js/functions.js"></script>
<script src="/js/dom.js"></script>
<script src="/js/dom.event.js"></script>
<script src="/js/utils.js"></script>
<script src="/js/debug.js"></script>
<!---->

<style>body {font-size:11px} pre {font:11px mono;border-bottom:1px solid #ddd; padding-bottom:0.3em; margin:0.3em;}</style>

<script src='lex3.js'></script>
<!--
<body>
<div style='top:20px;bottom:20px;width:300px;position:absolute'>
	<textarea id='oDict' style='width:100%;height:100%;font:11px mono'></textarea>
</div>

<div style='left:320px; right:20px; top:20px;bottom:20px;position:absolute'>
	<textarea id='oText' style='width:100%;height:100%;font:11px mono;display:none'></textarea>
	<a id='oShowTextLink' href='javascript:show_text()' style='font:22px Arial;'>Show text</a>
</div>
-->

<script>


var show_text = function() {
	get('oText').value = text;
	get('oText').style.display = 'block';
	get('oShowTextLink').style.display = 'none';
};


var text = load_file('cons.txt');
var dict = load_file('dict3.txt');
//alert(dict);
var dict_array = dict.split(/\n/);
var count = 0;

dict_array.pop();

var out = [];
for (var i = 0, f; i < dict_array.length; ++i)
	out[out.length] = re_escape(dict_array[i]);
var re = new RegExp(out.join('|'), 'g');
var actions = {};
for (var i = 0, f; i < dict_array.length; ++i) {
	f = new Function("count += " + dict_array[i].length);
	f.toString = (function(x){ return function(){ return x }})('action ' + dict_array[i]);
	f();
	f();
	actions[dict_array[i]] = f;
}


var l = (function() {
	var l = {};
	var dd = dict_array;
	for (var i = 0; i < dd.length; ++i)
		lex_merge(l, lex_re(parse_re(re_escape(dd[i])), actions[dd[i]]));
	lex_merge(l, lex_re(/./));
	return l;
})();

//trace(dict_array);
//alert(1);


//var lex = lex_gen(l);

//trace(l);

//trace(actions);


//trace(starts);


//get('oDict').value = dict;





var test = function(config) {
	var gen = config.gen;
	var f, result, t0, t1;
	f = config.func;
	if (!f && config.gen)
		f = config.gen();		
	if (!f) {
		alert('функция не определена');
		return;
	}
	try { f('zzz', re, actions); } catch(e) {};
	var n = 0, time = 0;
	//f('zzz', re, actions);
	do {
		t0 = new Date;
		result = f(text, re, actions);
		t1 = new Date;
		time += t1 - t0;
		++n;
	} while (time < 100);
	trace(sprintf('%s\n\nresult=%s, time=%.4f ms.', config.description, result, time / n));
};

/*
*/


var t1 = {
	description: 'перебор-прыжок: for - switch true',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    var count = 0;';
		out[out.length] = '    for (var i = 0, max = text.length ; i < max; ++i) ';
		out[out.length] = '        switch (true) {';
		var dd = dict_array;
		for (var i = 0; i < dd.length; ++i) {
			out[out.length] = sprintf('            case text.substr(i, %2d)  == %-20q: count += %2d; i += %2d; continue;', 
				dd[i].length, dd[i], dd[i].length, dd[i].length);
		}
		out[out.length] = '        }';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		out = '(' + out.join('\n') + ')';
		return eval(out);
	}
};
//trace('%s', t1.gen());
//test(t1);


var t1a = {
	description: 'перебор-прыжок с асс. массивом действий',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    count = 0;';
		out[out.length] = '    var f, empty_fn = function(){};';
		out[out.length] = '    for (var i = 0, max = text.length ; i < max; ++i) {';
		out[out.length] = '        (';
		var dd = dict_array;
		var assoc = {};
		for (var i = 0; i < dd.length; ++i) {
			if (assoc[dd[i].length]) continue;
			assoc[dd[i].length] = 1;
			out[out.length] = sprintf('            actions[text.substr(i, %2d)] ||', dd[i].length);
		}
		out[out.length] = '        empty_fn)()';
		out[out.length] = '    }';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		out = '(' + out.join('\n') + ')';
		//trace(out);
		return eval(out);
	}
};
//trace('%s', t1a.gen());




var t2 = {
	description: 'перебор-прыжок: for - if - continue',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    var count = 0;';
		out[out.length] = '    for (var i = 0, max = text.length ; i < max; ++i) {';
		var dd = dict_array;
		for (var i = 0; i < dd.length; ++i) {
			out[out.length] = sprintf('        if (text.substr(i, %2d)  == %-20q) { count += %2d; i += %2d; continue; }', 
				dd[i].length, dd[i], dd[i].length, dd[i].length);
		}
		out[out.length] = '    }';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		return eval('(' + out.join('\n') + ')');
	}
};
//trace('%s', gen_f1a());


var t2a = {
	description: 'перебор-прыжок: for - if - continue (с индексом)',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    var count = 0;';
		out[out.length] = '    for (var i = 0, max = text.length ; i < max; ++i)';
		out[out.length] = '        switch (text[i]) {';
		var dd = dict_array;
		var starts = {};
		var c;
		var i, j;
		for (i = 0; i < dd.length; ++i) {
			c = dd[i][0];
			if (!starts[c])
				starts[c] = [];
			starts[c].push(dd[i]);
		}
		for (i in starts) {
			out[out.length] = sprintf('            case %q:', i);
			dd = starts[i];
			for (j = 0; j < dd.length; ++j) {
				out[out.length] = sprintf('                if (text.substr(i, %2d)  == %-20q) { count += %2d; i += %2d; continue; }', 
					dd[j].length, dd[j], dd[j].length, dd[j].length);
			}
			out[out.length] = '                continue;';
		}
		out[out.length] = '        }';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		out = '(' + out.join('\n') + ')';
		//trace(out);
		return eval(out);
	}
};
//trace('%s', t2a.gen());



var t3 = {
	description: 'специальное решение: regexp - match - length',
	func: function(text, re, actions) {
		var mm = text.match(re);
		var result = 0;
		for (var i = 0, max = mm.length; i < max; ++i)
			result += mm[i].length;
		return result;
	}
};


var t4 = {
	description: 'рег. выражения: replace - switch - case - return',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    var count = 0;';
		out[out.length] = '    text.replace(re, function($0) { switch ($0) {';
		var dd = dict_array;
		for (var i = 0; i < dd.length; ++i) {
			out[out.length] = sprintf('        case %-20q: count += %2d; return "";', dd[i], dd[i].length);
		}
		out[out.length] = '    }});';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		out = '(' + out.join('\n') + ')';
		return eval(out);
	}
};
//trace('%s', t4.gen());

var t5 = {
	description: 'рег. выражения и асс. массив действий: replace - action',
	func: function(text, re, actions) {
		count = 0;
		text.replace(re, function($0){ actions[$0](); return '' });
		return count;
	}
};

var t6 = {
	description: 'рег. выражения: match - for - switch - case - continue',
	gen: function() {
		var out = [];
		out[out.length] = 'function(text, re, actions) {';
		out[out.length] = '    var count = 0;';
		out[out.length] = '    var mm = text.match(re);';
		out[out.length] = '    for (var i = 0, max = mm.length; i < max; ++i) switch (mm[i]) {';
		var dd = dict_array;
		for (var i = 0; i < dd.length; ++i) {
			out[out.length] = sprintf('        case %-20q: count += %2d; continue;', dd[i], dd[i].length);
		}
		out[out.length] = '    };';
		out[out.length] = '    return count;';
		out[out.length] = '}';
		out = '(' + out.join('\n') + ')';
		return eval(out);
	}
};
//trace('%s', t5.gen());

var t7 = {
	description: 'рег. выражения и асс. массив действий: match - for - action',
	func: function(text, re, actions) {
		count = 0;
		var mm = text.match(re);
		for (var i = 0, max = mm.length; i < max; ++i)
			actions[mm[i]]();
		return count;
	}
};

var t8 = {
	description: 'lex (dynamic)',
	func: function(text, re, actions) {
		count = 0;
		lex_run(l, text);
		return count;
	}
};


try {
var t9 = {
	description: 'lex (static)',
	func: (function(){
		var lex = lex_gen(l);
		return function(text) {
			count = 0;
			lex(text);
		}
	})()
};
} catch(e) {}


//trace('%s', t9.gen());
	

//test(t1);
//test(t1a);
//test(t2);
//test(t2a);
////test(t3);

test(t4);
test(t5);
test(t6);
test(t7);
test(t8);

if (window.t9)
	test(t9);

</script>




















